import { defineComponent,h, reactive, computed, onMounted, onUnmounted } from '@vue/runtime-core'
import Map from '../components/Map'
import MyPlane from '../components/Plane'
import EnemyPlane, { enemyPlaneInfo } from '../components/EnemyPlane'
import Bullet, { myBulletInfo, enemyBulletInfo } from '../components/Bullet'
import { moveBullets } from '../utils/moveBullets'
import { moveEnemyPlanes } from '../utils/moveEnemyPlanes'
import { hitCheckObj } from '../utils/index'
import { game } from '../Game'
import TWEEN from '@tweenjs/tween.js'
import { useKeyboardMove } from '../use/useKeyboardMove'

//创建我的飞机
const useMyPlane = ({ x, y, speed }) => {
    const myPlaneInfo = reactive({
        x,
        y,
        speed,
        width: 258,
        height: 364
    })
    //缓动出场
    const tween = new TWEEN.Tween({//初始状态数据
        x,
        y
    })
    tween.to({ //缓动结束后状态数据
        y: 600
    }, 1000)
    tween.start()//开始缓动
    tween.onUpdate((obj) =>{//obj：每次update后的数据，变更核心
        myPlaneInfo.y = obj.y
    })
    const handleTicker = ()=> {
        TWEEN.update()//平滑实现y值更改，在循环动画中调用，有平滑效果
    }
    //键盘控制飞机移动,游戏结束，页面跳转后kedown事件取消
    const { x: myPlaneX, y: myPlaneY } = useKeyboardMove({
        x: myPlaneInfo.x,
        y: myPlaneInfo.y,
        speed: myPlaneInfo.speed
    })
    onMounted(() => {
        game.ticker.add(handleTicker)
    })
    onUnmounted(() => {
        game.ticker.remove(handleTicker)
    })

    myPlaneInfo.x = myPlaneX
    myPlaneInfo.y = myPlaneY

    return myPlaneInfo
}

//创建我的子弹
const useMyBullets = () => {
    //子弹数组
    const myBullets = reactive([])

    //创建子弹,点击空格，调用
    const createMyBullet = (x, y) => {
        const width = myBulletInfo.width
        const height = myBulletInfo.height
        const dir = myBulletInfo.dir
        myBullets.push({x, y, width, height, dir})
    }
    //子弹移动，包括敌机子弹，单独封装
    
    return { myBullets, createMyBullet }
}

//创建敌机
const useEnemyPlanes = () => {
    const enemyPlanes = reactive([])

    const createEnemyPlane = (x) =>{
        return {
            x,
            y: -200,
            width: enemyPlaneInfo.width,
            height: enemyPlaneInfo.height,
            dir: 1,
            count: 0,
            life: enemyPlaneInfo.life
        }
    }
    setInterval(() => {
        const x = Math.floor((443*Math.random()))
        enemyPlanes.push(createEnemyPlane(x))
    }, 600)
    //每架敌机，每次移动，到边界就反向
    
    return enemyPlanes
}

//创建敌机子弹
const useEnemyBullets = () => {
    const enemyBullets = reactive([])
    //创建子弹
    const createEnemyBullet = (x, y) => {
        const width = enemyBulletInfo.width
        const height = enemyBulletInfo.height
        const dir = enemyBulletInfo.dir
        enemyBullets.push({x, y, width, height, dir})
    }

    return { enemyBullets, createEnemyBullet }
}

//战斗逻辑
const useFighting = ({ myBullets, enemyPlanes, enemyBullets, myPlane, gameOver }) => {
    const handleTicker = () =>{
        moveBullets(myBullets)
        moveEnemyPlanes(enemyPlanes)
        moveBullets(enemyBullets)

        //我方子弹碰撞
        myBullets.forEach((myBullet, index) => {
            //碰撞敌机
            enemyPlanes.forEach((enemyPlane, enemyPlaneIndex) => {
                if (hitCheckObj(myBullet, enemyPlane)) {
                    myBullets.splice(index, 1)
                    enemyPlane.life--
                    if (enemyPlane.life <= 0) {
                        enemyPlanes.splice(enemyPlaneIndex, 1)
                    }
                }
            })
            //碰撞子弹
            enemyBullets.forEach((enemyBullet, enemyBulletIndex) => {
                if (hitCheckObj(myBullet, enemyBullet)) {
                    myBullets.splice(index, 1)
                    enemyBullets.splice(enemyBulletIndex, 1)
                }
            })
        });

        //我方飞机碰撞
        const hitMyPlane = (enemyObj) => {
            if (hitCheckObj(myPlane, enemyObj)) {
                gameOver()
            }
        }
        //遍历敌机
        enemyPlanes.forEach((enemyPlane) =>{
            hitMyPlane(enemyPlane)
        })
        //遍历敌机子弹
        enemyBullets.forEach((enemyBullet) => {
            hitMyPlane(enemyBullet)
        })      
    }

    onMounted(() =>{
        game.ticker.add(handleTicker)
    })
    onUnmounted(() => {
        game.ticker.remove(handleTicker)
    })
}

export default defineComponent({
    setup(props, ctx){

        //获取我方飞机
        const myPlane = useMyPlane({
            x: 300,
            y: 1080,
            speed: 7
        })

        //获取我方子弹
        const { myBullets, createMyBullet } = useMyBullets()

        //获取敌机
        const enemyPlanes = useEnemyPlanes()

        //获取敌机子弹
        const { enemyBullets, createEnemyBullet } = useEnemyBullets()


        //战斗逻辑
        useFighting({
            myBullets,
            enemyPlanes,
            enemyBullets,
            myPlane,
            gameOver(){
                ctx.emit('changePage', 'endPage')
            }
        }) 

        return { 
            myPlane,
            myBullets,
            createMyBullet,
            enemyPlanes,
            enemyBullets,
            createEnemyBullet
        }
    },
    render(ctx){

        //创建我机
        const createMyPlane = () => {
            return h(MyPlane,{
                x: ctx.myPlane.x,
                y: ctx.myPlane.y,
                onAttack({x, y}) {
                    //console.log('有数据')
                    ctx.createMyBullet(x, y)
                    //console.log(ctx.myBullets)
                }})
        }

        //创建子弹(包括敌我机)
        const createBullet = (info,index) => {
            //console.log(info.x)
            return h(Bullet, {
                x: info.x,
                y: info.y,
                width: info.width,
                height: info.height,
                dir: info.dir
            })
        }

        //创建敌机
        const createEnemyPlane = (info) => {
            return h(EnemyPlane, {
                x: info.x,
                y: info.y,
                width: info.width,
                height: info.height,
                onAttack({x, y}){
                    ctx.createEnemyBullet(x, y)
                }
            })
        }

        return h('Container',[
            h(Map),
            createMyPlane(),
            ...ctx.myBullets.map(createBullet),
            ...ctx.enemyPlanes.map(createEnemyPlane),
            ...ctx.enemyBullets.map(createBullet)
           ])
            
    }
})




